#pragma once
#include "SolarThermalShow.h"

#define EVENT_LABELANI_TIMERID_BASE			(UIMSG_USER + 160) 
#define EVENT_LABELANI_PERIOD_TIMERID		(EVENT_LABELANI_TIMERID_BASE + 1) 
#define EVENT_LABELANI_NEXTACTION_TIMERID   (EVENT_LABELANI_TIMERID_BASE + 2)
 

#define EVENT_LABELANI_PERIOD_DEFAULT_DURATION			(500)  
#define EVENT_LABELANI_NEXTACTION_DEFAULT_DURATION		(5000)  

class CLabelAniUI : public CLabelUI, public SolarThermalShow
{
	DECLARE_DUICONTROL(CLabelAniUI)
public:
	CLabelAniUI() {

	}
	virtual ~CLabelAniUI() {

	}

	#define CLabelAniUI_CLASS_NAME _T("LabelAni")
	LPCTSTR GetClass() const
	{
		return CLabelAniUI_CLASS_NAME;
	}
	LPVOID GetInterface(LPCTSTR pstrName)
	{
		if (_tcscmp(pstrName, CLabelAniUI_CLASS_NAME) == 0) return static_cast<CLabelAniUI*>(this);
		return CLabelUI::GetInterface(pstrName);
	}
	
	virtual void DoEvent(TEventUI& event)
	{
		CLabelUI::DoEvent(event);

		if (event.Type == UIEVENT_TIMER)
		{
			OnTimer((UINT_PTR)event.wParam);
		}
	}

	virtual void OnTimer(UINT_PTR idEvent)
	{
		if (idEvent == EVENT_LABELANI_PERIOD_TIMERID) {
			DrawAniFrame();
			this->Invalidate();
		}
		else if (idEvent == EVENT_LABELANI_NEXTACTION_TIMERID) {
			ShowComplete();
		}
	}

	virtual void SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue)
	{
		CLabelUI::SetAttribute(pstrName, pstrValue);

		if (_tcsicmp(pstrName, _T("period")) == 0)
			SetPeriod(_ttoi(pstrValue));
		else if (_tcsicmp(pstrName, _T("nextact")) == 0)
			SetNextActInterval(_ttoi(pstrValue));
		else if (_tcsicmp(pstrName, _T("standardv")) == 0)
			SetStandardValue(_ttoi(pstrValue));
		else if (_tcsicmp(pstrName, _T("wavev")) == 0)
			SetWaveValue(_ttoi(pstrValue));
		else if (_tcsicmp(pstrName, _T("startv")) == 0)
			SetStartValue(_ttoi(pstrValue));
		else if (_tcsicmp(pstrName, _T("stepv")) == 0)
			SetStepValue(_ttoi(pstrValue));
		else if (_tcsicmp(pstrName, _T("wstatus")) == 0)
			SetWStatus(pstrValue);
		else if (_tcsicmp(pstrName, _T("resets")) == 0)
			SetResetStatus(pstrValue);
		else if (_tcsicmp(pstrName, _T("unit")) == 0)
			SetUnit(pstrValue);
		else if (_tcsicmp(pstrName, _T("anitype")) == 0)
			SetAniType(pstrValue);
		
	}

	void SetPeriod(int nValue)
	{
		m_nPeriod = nValue;
	}

	INT GetPeriod()
	{
		return m_nPeriod;
	}

	void SetNextActInterval(int nValue)
	{
		m_nInterval = nValue;
	}

	INT GetNextActInterval()
	{
		return m_nInterval;
	}

	void SetStandardValue(int nValue)
	{
		m_nStandardV = nValue;
	}

	INT GetStandardValue()
	{
		return m_nStandardV;
	}

	void SetWaveValue(int nValue)
	{
		m_nWaveV = nValue;
	}

	INT GetWaveValue()
	{
		return m_nWaveV;
	}

	void SetStartValue(int nValue)
	{
		m_nStartV = nValue;
	}

	INT GetStartValue()
	{
		return m_nStartV;
	}

	void SetStepValue(int nValue)
	{
		m_nStepV = nValue;
	}

	INT GetStepValue()
	{
		return m_nStepV;
	}

	LPCTSTR GetUnit()
	{
		return m_sUnit;
	}

	void SetUnit(LPCTSTR pStrImage)
	{
		m_sUnit = pStrImage;
		Invalidate();
	}

	LPCTSTR GetWStatus()
	{
		return m_sWStatus;
	}

	void SetWStatus(LPCTSTR pStrImage)
	{
		m_sWStatus = pStrImage;
		Invalidate();
	}

	LPCTSTR GetResetStatus()
	{
		return m_sResetStatus;
	}

	void SetResetStatus(LPCTSTR pStrImage)
	{
		m_sResetStatus = pStrImage;
		Invalidate();
	}

	INT GetAniType()
	{
		return m_AniType;
	}

	void SetAniType(LPCTSTR pStrType)
	{
		if (_tcsicmp(pStrType, _T("upvalue")) == 0) {
			m_AniType = ANI_UpValue;
		}
		else if (_tcsicmp(pStrType, _T("downvalue")) == 0) {
			m_AniType = ANI_DownValue;
		}
		else if (_tcsicmp(pStrType, _T("randonvalue")) == 0) {
			m_AniType = ANI_RandonValue;
		}
		else if (_tcsicmp(pStrType, _T("status")) == 0) {
			m_AniType = ANI_Status;
		}
		
		Invalidate();
	}

	virtual void  ToActFlowAnim() {
		ToPlayPeriod();
		if (m_NextPlayer.size() != 0) {
			m_bIsNextMode = true;
			m_pManager->SetTimer(this, EVENT_LABELANI_NEXTACTION_TIMERID, m_nInterval);
		}
		else {
			m_bIsNextMode = false;
		}
	}
	virtual void ToResetFlowAnim() {
		m_pManager->KillTimer(this, EVENT_LABELANI_NEXTACTION_TIMERID);
		ToStopPeriod();
		SolarThermalShow::Reset();
		Reset();
		this->Invalidate();
	}
	virtual void ToStopFlowAnim() {
		m_pManager->KillTimer(this, EVENT_LABELANI_NEXTACTION_TIMERID);
		ToStopPeriod();
		Reset();
		this->Invalidate();
	}
	virtual void SetNextAnimPlayer(SolarThermalShow* next) {
		m_NextPlayer.insert(next);
	}
	virtual void ShowComplete() {
		m_pManager->KillTimer(this, EVENT_LABELANI_NEXTACTION_TIMERID);

		for (set<SolarThermalShow*>::iterator iter = m_NextPlayer.begin(); iter != m_NextPlayer.end(); iter++) {
			if (m_bIsNextMode) {
				(*iter)->ToActFlowAnim();
			}
		}
	}

public:
		void ToPlayPeriod() {
			m_nCurrentV = GetStartValue();
			m_pManager->SetTimer(this, EVENT_LABELANI_PERIOD_TIMERID, m_nPeriod);
		}
		void ToStopPeriod() {
			m_pManager->KillTimer(this, EVENT_LABELANI_PERIOD_TIMERID);
		}
		void Reset() {
			//SetVale(GetStandardValue());
			SetText(GetResetStatus());
		}

private:
	void SetVale(INT value) {
		TCHAR szMsg[30];
		::wsprintf(szMsg, _T("%d%s"), value, GetUnit());
		SetText(szMsg);
	}
	void DrawAniFrame()
	{
		INT aniType = GetAniType();
		switch (aniType) {
		case ANI_UpValue:
			UpValuesAni();
			break;
		case ANI_DownValue:
			DownValueAni();
			break;
		case ANI_RandonValue:
			RandonAni();
			break;
		case ANI_Status:
			StatusAni();
			break;
		default:
			break;
		}
	}

	void UpValuesAni() 
	{
		m_pManager->KillTimer(this, EVENT_LABELANI_PERIOD_TIMERID);
		
		if (m_nCurrentV < m_nStandardV) {
			m_nCurrentV = m_nCurrentV + GetStepValue();
			if (m_nCurrentV > m_nStandardV) {
				m_nCurrentV = m_nStandardV;
			}
		}
		SetVale(m_nCurrentV);

		if (m_nCurrentV != m_nStandardV) {
			m_pManager->SetTimer(this, EVENT_LABELANI_PERIOD_TIMERID, m_nPeriod);
		}
	}

	void DownValueAni() {
		m_pManager->KillTimer(this, EVENT_LABELANI_PERIOD_TIMERID);

		if (m_nCurrentV > m_nStandardV) {
			m_nCurrentV = m_nCurrentV - GetStepValue();
			if (m_nCurrentV < m_nStandardV) {
				m_nCurrentV = m_nStandardV;
			}
		}
		SetVale(m_nCurrentV);

		if (m_nCurrentV != m_nStandardV) {
			m_pManager->SetTimer(this, EVENT_LABELANI_PERIOD_TIMERID, m_nPeriod);
		}
	}

	void RandonAni() {
		m_pManager->KillTimer(this, EVENT_LABELANI_PERIOD_TIMERID);

		/// to do 
		srand((unsigned)GetTickCount());
		INT	nValue = (rand() % GetWaveValue() - GetWaveValue() / 2);
		SetVale(GetStandardValue() + nValue);

		/// to period act:
		m_pManager->SetTimer(this, EVENT_LABELANI_PERIOD_TIMERID, m_nPeriod);
	}

	void StatusAni() {
		m_pManager->KillTimer(this, EVENT_LABELANI_PERIOD_TIMERID);
		SetText(GetWStatus());
	}


private:
	INT		m_nPeriod = EVENT_LABELANI_PERIOD_DEFAULT_DURATION;
	INT		m_nInterval = EVENT_LABELANI_NEXTACTION_DEFAULT_DURATION;

	INT		m_nStandardV = 0;
	INT		m_nWaveV = 0;
	INT		m_nStartV = 0;
	INT		m_nStepV = 0;
	INT		m_nCurrentV = 0;

	CDuiString	m_sUnit = _T("");
	CDuiString	m_sWStatus = _T("");
	CDuiString	m_sResetStatus = _T("");

	enum {
		ANI_UpValue = 0,
		ANI_DownValue,
		ANI_RandonValue,
		ANI_Status
	} m_AniType = ANI_RandonValue;
};



